package com.bjsxt.controller.erp;

import cn.hutool.core.lang.Snowflake;
import com.bjsxt.aspectj.annotation.Log;
import com.bjsxt.constants.Constants;
import com.bjsxt.controller.BaseController;
import com.bjsxt.domain.Purchase;
import com.bjsxt.domain.PurchaseItem;
import com.bjsxt.dto.PurchaseDto;
import com.bjsxt.dto.PurchaseFormDto;
import com.bjsxt.service.PurchaseService;
import com.bjsxt.utils.IdGeneratorSnowflake;
import com.bjsxt.utils.ShiroSecurityUtils;
import com.bjsxt.vo.AjaxResult;
import com.bjsxt.vo.DataGridView;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.apache.dubbo.config.annotation.Reference;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author:liao
 * @Description:TODO 采购信息控制器
 * @date:2020/12/23
 */
@RestController
@RequestMapping("erp/purchase")
@Transactional
public class PurchaseController extends BaseController {

    @Reference
    private PurchaseService purchaseService;

    /**
     * 分页查询所有采购入库列表信息
     */
    @GetMapping("listPurchaseForPage")
    public AjaxResult listPurchaseForPage(PurchaseDto purchaseDto){
        DataGridView dataGridView = purchaseService.listPurchasePage(purchaseDto);
        return AjaxResult.success("查询成功",dataGridView.getData(),dataGridView.getTotal());
    }

    /**
     * 分页查询待审核的单据
     */
    @GetMapping("listPurchasePendingForPage")
    @HystrixCommand
    public AjaxResult listPurchasePendingForPage(PurchaseDto purchaseDto){
        purchaseDto.setStatus(Constants.STOCK_PURCHASE_STATUS_2);
        DataGridView dataGridView = purchaseService.listPurchasePage(purchaseDto);
        return AjaxResult.success("查询成功",dataGridView.getData(),dataGridView.getTotal());
    }

    /**
     * 提交审核
     * 状态为未提交1和审核失败4的可以进行提交审核
     */
    @PostMapping("doAudit/{purchaseId}")
    @HystrixCommand
    public AjaxResult doAudit(@PathVariable String purchaseId){
        // 根据采购单据id查询单据对象
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断状态
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1)||purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4)){
            // 进行提交审核
            int i = purchaseService.doAudit(purchaseId, ShiroSecurityUtils.getCurrentSimpleUser());
            return AjaxResult.toAjax(i);
        }else {
            return AjaxResult.fail("当前状态不是【未提交】或【审核失败状态】不能提交审核");
        }
    }

    /**
     * 作废
     * 状态为未提交1和审核失败4的可以进行作废
     */
    @PostMapping("doInvalid/{purchaseId}")
    @HystrixCommand
    @Log(title = "作废")
    public AjaxResult doInvalid(@PathVariable String purchaseId){
        // 根据采购单id查询采购单对象
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断状态
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1)||purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4)){
            // 进行作废
            int i = purchaseService.doInvalid(purchaseId);
            return AjaxResult.toAjax(i);
        }else{
            return AjaxResult.fail("当前状态不是【未提交】或【审核失败状态】不能进行作废");
        }
    }

    /**
     * 审核通过
     * 状态为 待审核2的可以进行审核通过
     */
    @PostMapping("auditPass/{purchaseId}")
    @HystrixCommand
    @Log(title = "进行审核==>审核通过")
    public AjaxResult auditPass(@PathVariable String purchaseId){
        // 根据采购单据id查询采购单对象
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断状态
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_2)){
            // 进行审核
            int i = purchaseService.auditPass(purchaseId);
            return AjaxResult.toAjax(i);
        }else {
            return AjaxResult.fail("当前状态不是【待审核】,不能进行审核成功操作");
        }
    }

    /**
     * 审核不通过
     * 状态为待审核2的时候可以进行审核不通过
     * @param purchaseId 采购单id
     * @param auditMsg 审核不通过原因
     * @return
     */
    @PostMapping("auditNoPass/{purchaseId}/{auditMsg}")
    @HystrixCommand
    @Log(title = "进行审核==>审核不通过")
    public AjaxResult auditNoPass(@PathVariable String purchaseId,@PathVariable String auditMsg){
        // 根据采购单id查询采购单对象
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断状态
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_2)){
            // 进行审核
            int i = purchaseService.auditNoPass(purchaseId, auditMsg);
            return AjaxResult.toAjax(i);
        }else {
            return AjaxResult.fail("当前状态不是【待审核】，不能进行审核");
        }
    }

    /**
     * 根据采购单id查询采购信息列表
     */
    @GetMapping("getPurchaseItemById/{purchaseId}")
    @HystrixCommand
    public AjaxResult getPurchaseItemById(@PathVariable String purchaseId){
        List<PurchaseItem> purchaseItems = purchaseService.getPurchaseItemById(purchaseId);
        return AjaxResult.success(purchaseItems);
    }


    /**
     * 点击新增采购生成采购单主表ID
     */
    @GetMapping("generatePurchaseId")
    public AjaxResult generatePurchaseId(){
        return AjaxResult.success("生成成功",IdGeneratorSnowflake.generatorIdWithProfix(Constants.PURCHASE_ID_PREFIX));
    }

    /**
     * 暂存采购单主表数据和详情数据 暂存与保存的区别是 暂存需要修改状态为未提交 保存需要将状态修改为待审核状态
     */
    @PostMapping("addPurchase")
    @HystrixCommand
     public AjaxResult addPurchase(@RequestBody PurchaseFormDto purchaseFormDto){
        // 判断当前采购单状态
        if (!checkPurchase(purchaseFormDto)){
            return AjaxResult.fail("当前采购单不能进行暂存==>状态不是未提交或审核失败状态||主表信息不存在");
        }
        // 设置当前登录用户
        purchaseFormDto.setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
        // 暂存采购单主表数据和详情数据
        return AjaxResult.toAjax(purchaseService.addPurchaseAndItem(purchaseFormDto));
     }

    /**
     * 保存并提交采购单主表数据和详情数据 暂存与保存的区别是 暂存需要修改状态为未提交 保存需要将状态修改为待审核状态
     */
    @PostMapping("addPurchaseToAudit")
    @HystrixCommand
    public AjaxResult addPurchaseToAudit(@RequestBody PurchaseFormDto purchaseFormDto){
        // 判断当前采购单状态
        if (!checkPurchase(purchaseFormDto)){
            return AjaxResult.fail("当前采购单不能进行保存提交==>状态不是未提交或审核失败状态" +
                    "||主表信息不存在");
        }
        // 设置当前登录用户
        purchaseFormDto.setSimpleUser(ShiroSecurityUtils.getCurrentSimpleUser());
        // 暂存采购单主表数据和详情数据
        return AjaxResult.toAjax(purchaseService.addPurchaseAndItemToAudit(purchaseFormDto));
    }

    /**
     * 将判断采购单的状态抽取为一个公共方法
     */
    private boolean checkPurchase(PurchaseFormDto purchaseFormDto){
        // 获取采购单主表ID
        String purchaseId = purchaseFormDto.getPurchaseDto().getPurchaseId();
        // 根据采购单主表id查询采购单主表信息
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断采购单主表信息是否存在 若存在 返回true表示可以进行暂存
        // 为了防止下面的操作会有空指针现象 所以进行了判断
        if (null==purchase){
            return true;
        }
        // 判断当前采购单的状态 必须是Constants.STOCK_PURCHASE_STATUS_1 未提交
        // 和Constants.STOCK_PURCHASE_STATUS_4 审核失败 才能进行暂存
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_1)||
                purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_4)){
            return  true;
        }
        // 返回false表示状态不符合或者是采购单主表信息不存在
        return false;
    }

    /**
     * 根据采购单号查询采购单主表信息和详情信息
     */
    @GetMapping("queryPurchaseAndItemByPurchaseId/{purchaseId}")
    @HystrixCommand
    public AjaxResult queryPurchaseAndItemByPurchaseId(@PathVariable String purchaseId){
        // 根据采购单主表id查询采购单主表信息
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        // 判断
        if (null==purchase){
            return AjaxResult.fail("采购单号【"+purchaseId+"不存在】");
        }else {
            // 根据采购单主表id查询采购单详情
            List<PurchaseItem> purchaseItems = purchaseService.getPurchaseItemById(purchaseId);
            Map<String,Object> res = new HashMap<>();
            res.put("purchase",purchase);
            res.put("items",purchaseItems);
            return AjaxResult.success(res);
        }
    }

    /**
     * 根据采购单主表单号进行入库 采购单主表状态必须是审核成功才能入库
     */
    @HystrixCommand
    @GetMapping("doInventory/{purchaseId}")
    public AjaxResult doInventory(@PathVariable String purchaseId){
        // 根据采购单主表id查询采购单主表信息
        Purchase purchase = purchaseService.getPurchaseById(purchaseId);
        if (null==purchase){
            return AjaxResult.fail("采购单号【"+purchaseId+"不存在】");
        }
        // 判断状态 状态必须是Constants.STOCK_PURCHASE_STATUS_3 审核通过 才能进行入库
        if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_3)){
            // 进行入库
            return AjaxResult.toAjax(purchaseService.doInventory(purchaseId,ShiroSecurityUtils.getCurrentSimpleUser()));
        }else if (purchase.getStatus().equals(Constants.STOCK_PURCHASE_STATUS_6)){
            return AjaxResult.fail("采购单【"+purchaseId+"】已入库 不能再次进行入库");
        }else {
            return AjaxResult.fail("采购单【"+purchaseId+"】没有审核通过,不能入库");
        }
    }
}
